home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mac-Source 1994 July
/
Mac-Source_July_1994.iso
/
C and C++
/
Compilers⁄Interps
/
kevoSource
/
portWindows.c
< prev
next >
Wrap
Text File
|
1993-05-12
|
12KB
|
469 lines
/* Kevo -- a prototype-based object-oriented language */
/* (c) Antero Taivalsaari 1991-1993 */
/* Some parts (c) Antero Taivalsaari 1986-1988 */
/* portWindows.c: Non-portable window operations */
/*
This file contains structures and operations which are not
portable from one machine platform to another.
*/
#include "global.h"
#include "portGlobal.h"
/*---------------------------------------------------------------------------*/
/* Generic printing operations */
/*
These printing operations are pretty complicated, because the system must
automatically recognize whether the output device is a file (outfile != NIL),
or whether the window has a TextEdit or not. For files, we use normal C
fprintf function, but for other forms of I/O an appropriate toolbox routine
will be selected (either a TextEdit or QuickDraw routine).
*/
void ownPrintf(format, data)
char* format;
void* data;
{
WindowPtr thisWindow;
TEHandle thisTE;
int len;
if (!outfile) { /* Output to screen */
/* If the task has no associated window, ignore printing */
thisWindow = (WindowPtr)(*up)->window;
if (!thisWindow) return;
/* Format the data */
len = (unsigned char)sprintf(charbuffer, format, data);
if (thisTE = getWindowTE(thisWindow)) {
TEInsert(charbuffer, len, thisTE);
}
else { /* window has no associated TE -> use QuickDraw */
GrafPtr savePort;
GetPort(&savePort);
SetPort(thisWindow);
DrawString(CtoPstr(charbuffer));
SetPort(savePort);
}
}
else { /* Output to file */
fprintf(outfile, format, data);
fflush(outfile);
}
}
/*
This operation is needed, because files and screen use different characters
for separating the lines (files = LF, screen = CR).
*/
void ownCr()
{
WindowPtr thisWindow;
TEHandle thisTE;
if (!outfile) { /* Output to screen */
/* If the task has no associated window, ignore printing */
thisWindow = (WindowPtr)(*up)->window;
if (!thisWindow) return;
if (thisTE = getWindowTE(thisWindow)) TEKey(CR, thisTE);
else { /* window has no associated TE -> use QuickDraw */
GrafPtr savePort;
Point pt;
GetPort(&savePort);
SetPort(thisWindow);
GetPen(&pt);
/* Try to approximate a correct pen movement */
pt.h = 4;
pt.v += 12;
MoveTo(pt.h, pt.v);
SetPort(savePort);
}
}
else { /* Output to file */
fprintf(outfile, "\n");
fflush(outfile);
}
}
/*---------------------------------------------------------------------------*/
/* Window information field operations */
/* Create a window information structure */
/*
Each Kevo window must contain one of these structures stored
its 'RefCon' field.
*/
WINFO* createWinfo(kind, conf1)
int kind; /* Window kind (see 'portGlobal.h') */
void* conf1; /* Additional window information */
{
WINFO* newWinfo = (WINFO*)mycalloc(1, sizeof(WINFO));
newWinfo->wKind = kind;
newWinfo->wConF1 = conf1;
newWinfo->wConF2 = 0;
newWinfo->wConF3 = 0;
return (newWinfo);
}
/* Delete a window information structure */
/*
Note that this routine does not delete the possible associated
TextEdit or List structure.
*/
void deleteWinfo(thisWindow)
WindowPtr thisWindow;
{
WINFO* thisWinfo = (WINFO*)GetWRefCon(thisWindow);
free(thisWinfo);
}
/* Return the window information field */
TEHandle getWindowTE(thisWindow)
WindowPtr thisWindow;
{
WINFO* thisWinfo = (WINFO*)GetWRefCon(thisWindow);
if (thisWinfo && thisWinfo->wKind == TEWKind)
return((TEHandle)thisWinfo->wConF1);
else return(NIL);
}
/* Return window kind info */
int getWindowKind(thisWindow)
WindowPtr thisWindow;
{
WINFO* thisWinfo = (WINFO*)GetWRefCon(thisWindow);
if (thisWinfo) return(thisWinfo->wKind);
else return(UnknownWKind);
}
ListHandle getBrowserIcons(browserWindow)
WindowPtr browserWindow;
{
WINFO* thisWinfo = (WINFO*)GetWRefCon(browserWindow);
if (thisWinfo && (thisWinfo->wKind == BrowserWKind || thisWinfo->wKind == CloneBrWKind))
return((ListHandle)thisWinfo->wConF1);
else return(NIL);
}
void setBrowserIcons(browserWindow, iconList)
WindowPtr browserWindow;
ListHandle iconList;
{
WINFO* thisWinfo = (WINFO*)GetWRefCon(browserWindow);
if (thisWinfo) thisWinfo->wConF1 = iconList;
}
char* getBrowserIdent(browserWindow)
WindowPtr browserWindow;
{
WINFO* thisWinfo = (WINFO*)GetWRefCon(browserWindow);
if (thisWinfo && thisWinfo->wKind == BrowserWKind)
return((char*)thisWinfo->wConF2);
else return(NIL);
}
void setBrowserIdent(browserWindow, ident)
WindowPtr browserWindow;
char* ident;
{
WINFO* thisWinfo = (WINFO*)GetWRefCon(browserWindow);
if (thisWinfo) thisWinfo->wConF2 = ident;
}
OBJECT* getMethodContext(browserWindow)
WindowPtr browserWindow;
{
WINFO* thisWinfo = (WINFO*)GetWRefCon(browserWindow);
if (thisWinfo && thisWinfo->wKind == TEWKind)
return((OBJECT*)thisWinfo->wConF2);
else return(NIL);
}
void setMethodContext(browserWindow, object)
WindowPtr browserWindow;
OBJECT* object;
{
WINFO* thisWinfo = (WINFO*)GetWRefCon(browserWindow);
if (thisWinfo) thisWinfo->wConF2 = object;
}
PAIR* getMethodPair(browserWindow)
WindowPtr browserWindow;
{
WINFO* thisWinfo = (WINFO*)GetWRefCon(browserWindow);
if (thisWinfo && thisWinfo->wKind == TEWKind)
return((PAIR*)thisWinfo->wConF3);
else return(NIL);
}
void setMethodPair(browserWindow, pair)
WindowPtr browserWindow;
PAIR* pair;
{
WINFO* thisWinfo = (WINFO*)GetWRefCon(browserWindow);
if (thisWinfo) thisWinfo->wConF3 = pair;
}
/*---------------------------------------------------------------------------*/
/* User interface tools */
/* Build a plain window (without any TE facilities) */
WindowPtr buildWindow(title)
char* title;
{
WindowPtr origWindow = NIL;
WindowPtr newWindow;
Rect newRect;
WINFO* newWinfo;
WStateData** wDataHdl;
static count1 = 0; /* Note: this is a static variable */
static count2 = 0; /* Note: this is a static variable */
/* If we are not in the supervisor mode, and the task which is creating */
/* the new window has a window, copy size information from that window */
/* Otherwise, copy the info from the frontmost window on the screen */
if (!supervisor) origWindow = (WindowPtr)(*up)->window;
if (!origWindow) origWindow = FrontWindow();
/* Copy size information from the currently active window */
BlockMove(&origWindow->portRect, &newRect, sizeof(Rect));
++count1;
/* Place the window below and right of the current window */
OffsetRect(&newRect, 60 + count1*10 + count2*7, 80 + count1*10 + count2*3);
if (count1 > 20) {
count1 = 0;
count2++;
if (count2 > 15) count2 = 0;
}
/* New window is created under the frontmost window */
if (!(newWindow = NewWindow(0L, /* Storage: from heap` */
&newRect, /* Location and size rectangle */
title, /* The title of the window */
FALSE, /* Initially visible: false */
documentProc+8, /* The kind of the window */
FrontWindow(), /* Is behind the frontmost window */
TRUE, /* Has a close box: yes */
0L))) /* refCon field is initially NIL */
return(NIL);
/* Set the standard size of the window for zooming */
wDataHdl = (WStateData**)((WindowPeek)newWindow)->dataHandle;
BlockMove(&standardRect, &(*wDataHdl)->stdState, sizeof(Rect));
/* Create a window information structure for a plain window */
newWinfo = createWinfo(PlainWKind, NIL);
/* Then set the RefCon field of the new window to point to the winfo struct */
SetWRefCon(newWindow, (long)newWinfo);
return(newWindow);
}
/* Build a window with TE facilities */
WindowPtr buildTEWindow(title)
char* title;
{
WindowPtr newWindow, savePort;
Rect viewRect, destRect;
TEHandle newText;
WINFO* thisWinfo;
if (!(newWindow = buildWindow(title))) return(NIL);
GetPort(&savePort);
SetPort(newWindow);
TextFont(monaco);
TextFace(0);
TextSize(9);
BlockMove(&newWindow->portRect, &viewRect, sizeof(Rect));
viewRect.right -= SCROLLBARWIDTH;
viewRect.bottom -= SCROLLBARWIDTH;
BlockMove(&newWindow->portRect, &destRect, sizeof(Rect));
destRect.right -= (SCROLLBARWIDTH + 4);
destRect.bottom -= (SCROLLBARWIDTH + 4);
destRect.left += 4;
newText = TENew(&destRect, &viewRect);
if (!newText) return(NIL);
SetPort(savePort);
/* Set automatic scrolling */
TEAutoView(TRUE, newText);
/*
Change the associated window information struct to reflect on
the fact that the window is now a TextEdit window.
*/
thisWinfo = (WINFO*)GetWRefCon(newWindow);
thisWinfo->wKind = TEWKind;
thisWinfo->wConF1 = newText;
return(newWindow);
}
/* Given a window, find a foreground task which is associated to that window */
/* Return NIL if the window has no associated foreground task */
TASK** determineTask(thisWindow)
WindowPtr thisWindow;
{
TASK** thisTask = firstTask;
/* Walk through all the tasks in the system */
/* and return the first one pointing to the requested window */
/* This is normally the task which originally created the window */
/* (unless the original task has been deleted) */
while(thisTask) {
if ((WindowPtr)(*thisTask)->window == thisWindow) return(thisTask);
thisTask = (*thisTask)->nextTask;
}
return(NIL);
}
/* Given a window, delete it and all the associated tasks */
/* provided that none of these tasks is running */
/* Also delete the window information structure stored in the RefCon field */
void deleteWindow(thisWindow)
WindowPtr thisWindow;
{
TASK** thisTask;
int success = TRUE;
while((thisTask = determineTask(thisWindow)) && (success = killTask(thisTask)));
if (success) {
/* Tasks were deleted without any problems */
TEHandle thisTE = getWindowTE(thisWindow);
if (thisTE) TEDispose(thisTE);
deleteWinfo(thisWindow);
DisposeWindow(thisWindow);
theText = NIL;
/* theTask = NIL; */
}
else {
/* Otherwise the window cannot be closed */
theTask = thisTask;
fprintf(confile, "== Cannot delete the only active task in the system ==\n");
}
}
/* Given a window, resize the window by doing the appropriate changes
/* in its possible TE structure */
void resizeWindowTE(thisWindow)
WindowPtr thisWindow;
{
TEHandle thisTE;
Rect viewRect, destRect;
if (thisTE = getWindowTE(thisWindow)) {
BlockMove(&thisWindow->portRect, &viewRect, sizeof(Rect));
viewRect.right -= SCROLLBARWIDTH;
viewRect.bottom -= SCROLLBARWIDTH;
BlockMove(&thisWindow->portRect, &destRect, sizeof(Rect));
destRect.right -= (SCROLLBARWIDTH + 4);
destRect.bottom -= (SCROLLBARWIDTH + 4);
destRect.left += 4;
BlockMove(&viewRect, &(*thisTE)->viewRect, sizeof(Rect));
BlockMove(&destRect, &(*thisTE)->destRect, sizeof(Rect));
TECalText(thisTE);
TESelView(thisTE);
}
}
/* Count the number of visible windows (belonging to Kevo) */
int countVisibleWindows()
{
WindowPeek thisWindow = (WindowPeek)FrontWindow();
int count = 0;
while (thisWindow) {
if (thisWindow->visible) count++;
thisWindow = thisWindow->nextWindow;
}
return(count);
}
/*
Replace possible meta characters from window names with "safe" chars.
Meta characters would cause the window menus entries to be blurred.
*/
void replaceMenuMetas(string)
char* string; /* The parameter is actually a Pascal string */
{
short len = (short)*string;
char* ptr = string+1;
while (len--) {
switch (*ptr) {
case ';':
case '^':
case '!':
case '<':
case '/':
case '(':
/* The rest are not metas but are replaced anyway */
case ')':
case '>':
*ptr = '_';
break;
}
ptr++;
}
}